import React from 'react';
import styles from './index.less';
import {Col, Row} from 'antd';
import {Modal, ActionSheet, Toast, Badge} from 'antd-mobile';
import {backMoveImg, failImg, chatImg, peaceImg, chatHistoryImg, skinImg} from '@/utils/images-res';
import {secondsToMinuteStr} from '@/utils/board-utils';
import SocketEvent from '@/service/event';
import {btnSound, messageSound, playSound} from '@/utils/sounds-res';
import {log} from '@/utils/log-utils';
import config from '@/config';
import AdvancedBtn from "@/button";
import {resMap} from "@/utils/map-res";

/**
 * 用户信息展示
 */
class User extends React.Component {

  constructor(props) {
    super(props);

    this.state = {
      // 聊天窗口是否展示
      msgWindowShow: false,
      // 消息记录
      chatHistory: [],
      // 观战消息展示记录(仅临时缓存和展示)
      watchChatCache: [],
      watchChatObj: null,
      watchChatShow: false,
      /** -- 聊天信息 -- */
      userMsg: null,
      enemyMsg: null,
      userMsgShow: false,
      enemyMsgShow: false,
      userStartDate: null,
      enemyStartDate: null,
      /** -- 用户离线信息 -- */
      offlineMsgShow: false,
      offlineMsg: null,
      // 离线时间（日期时间戳）
      offlineTime: null,
      // 离线超时限期（秒）
      offlineTimeout: null,
      // 观战人数
      watchUserList: [],
      // 观战弹窗是否展示
      watchWindowShow: false,
    };

    this.chatRespId = 'boardChatRespId';
    this.enemyOfflineRespId = 'boardEnemyOfflineRespId';
    this.enemyOnlineRespId = 'boardEnemyOnlineRespId';
    this.sendPeaceRespId = 'boardSendPeaceRespId';
    this.sendPeaceResultRespId = 'boardSendPeaceResultRespId';
    this.backMoveRespId = 'boardBackMoveRespId';
    this.backMoveResultRespId = 'boardBackMoveResultRespId';
    this.watchNotifyRespId = 'boardWatchNotifyRespId';

    this.unRegisterServices = [];
    this.unRegisterServices.push(this.chatRespId);
    this.unRegisterServices.push(this.enemyOfflineRespId);
    this.unRegisterServices.push(this.enemyOnlineRespId);
    this.unRegisterServices.push(this.sendPeaceRespId);
    this.unRegisterServices.push(this.sendPeaceResultRespId);
    this.unRegisterServices.push(this.backMoveRespId);
    this.unRegisterServices.push(this.backMoveResultRespId);
    this.unRegisterServices.push(this.watchNotifyRespId);

    this.chat = '聊天';
    this.chatHistory = '消息记录'
    this.peace = '求和';
    this.backMove = '悔棋';
    this.fail = '认输';
    this.skin = '换肤';

    // 求和、悔棋枚举
    this.agree = 'agree';
    this.reject = 'reject';
    // 消息滚动条组件
    this.listRef = null;
  }

  componentDidMount() {
    // 处理消息倒计时
    this.handleChatMessageTimeout();
    // 用户离线倒计时
    this.handleOfflineMessageTimeout();
    // 观战用户信息显示监听
    this.handleWatchChatTimeout();
    // 开启消息监听
    this.startMessageListen();
    // 请求观战人数
    this.sendWatchCount(false);
    // 初始化头像进度canvas
    this.initCanvas();
    // 页面显/隐的事件
    document.addEventListener('visibilitychange', this.sendWatchCount);
  }

  initCanvas = () => {
    setTimeout(() => {
      const {headCanvas, playOne, playTwo} = this.props;
      const nodes = [];
      nodes.push({userId: playOne.userId, el: this.playOneRef});
      nodes.push({userId: playTwo.userId, el: this.playTwoRef});
      headCanvas.initBinds(nodes);
    }, 0);
  }

  /**
   * 请求观战人数数据
   */
  sendWatchCount = (hidden) => {
    const isHidden = hidden || document.hidden;
    if (!isHidden) {
      SocketEvent.emit(this.props.socket, 'watchCountApi', {
        userId: this.props.userId,
        roomId: this.props.roomId
      }, resp => {
        log("请求观战人数数据返回：", resp);
      });
    }
  }

  /**
   * 对方发送消息监听
   */
  startMessageListen = () => {
    // 本局在观战数据统计
    SocketEvent.register('watchNotifyRespApi', this.watchNotifyRespId, resp => {
      log('对局时有用户加入或离开观战，resp: ', resp);
      if (resp.code === 'success') {
        const {action, watchUserId, watchUserName, watchUserList} = resp.data;
        // 全量数据
        if (action === 'update') {
          this.setState({watchUserList});
          // 增量数据
        } else if (action === 'add' || action === 'sub') {
          const stateWatchUserList = this.state.watchUserList;
          const userIndex = stateWatchUserList.findIndex(user => user.userId === watchUserId);
          if (action === 'add' && userIndex === -1) {
            stateWatchUserList.push({userId: watchUserId, userName: watchUserName});
          } else if (action === 'sub' && userIndex !== -1) {
            stateWatchUserList.splice(userIndex, 1);
          }
          this.setState({watchUserList: stateWatchUserList});
        }
      }
    });

    // 聊天信息监听
    SocketEvent.register('chatRespApi', this.chatRespId, resp => {
      log('聊天消息，返回：', resp);
      if (resp.code === 'success') {
        const {chatHistory, watchChatCache} = this.state;
        const {userId, userName, content} = resp.data;
        const {playOne, playTwo} = this.props;

        const sendMsgObj = {
          userId: userId,
          userName: userName,
          content: content,
        };
        // 记录消息内容
        chatHistory.push(sendMsgObj);

        // 对战方的消息处理
        if (userId === playOne.userId || userId === playTwo.userId) {
          this.setState({
            enemyMsg: content,
            enemyMsgShow: true,
            enemyStartDate: null,
            chatHistory,
          });
        } else {
          // 观战方的消息处理
          watchChatCache.push(sendMsgObj);
          // 有新消息进来，watchChatShow不显示，交由下一次显示最新消息
          this.setState({watchChatCache, watchChatShow: false});
        }
        // 拖动聊天消息窗口的滚动条到底部
        this.msgWindowToBottom();
        playSound(messageSound);
      } else {
        Toast.show(resp.msg);
      }
    });

    // 对方离线监听
    SocketEvent.register('enemyOfflineRespApi', this.enemyOfflineRespId, resp => {
      log('用户离线消息，返回：', resp);
      if (resp.code === 'success') {
        const {userId, offlineTime, offlineTimeout} = resp.data;
        if (this.props.userId !== userId) {
          this.setState({
            offlineMsgShow: true,
            // 离线时间（日期）
            offlineTime: offlineTime,
            // 离线超时限期（秒）
            offlineTimeout: offlineTimeout,
          });
        }
      }
    });
    // 对方上线监听
    SocketEvent.register('enemyOnlineRespApi', this.enemyOnlineRespId, resp => {
      log('对方上线消息，返回：', resp);
      if (resp.code === 'success') {
        this.setState({
          offlineMsgShow: false,
          offlineMsg: null,
        });
      }
    });
    // 对方发起求和监听
    SocketEvent.register('sendPeaceRespApi', this.sendPeaceRespId, resp => {
      log('对方发起求和，返回：', resp);
      if (resp.code === 'success') {
        Modal.alert('系统提示', '对方发起求和', [
          {
            text: '拒绝', onPress: () => {
              playSound(btnSound);
              SocketEvent.emit(this.props.socket, 'sendPeaceResultApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                result: this.reject,
                battleId: this.props.battleId,
              }, resp => {
                if (resp.code !== 'success') {
                  Toast.show(resp.msg);
                }
              });
            },
          },
          {
            text: '同意', onPress: () => {
              playSound(btnSound);
              SocketEvent.emit(this.props.socket, 'sendPeaceResultApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                result: this.agree,
                battleId: this.props.battleId,
              }, resp => {
                if (resp.code !== 'success') {
                  Toast.show(resp.msg);
                }
              });
            },
          },
        ]);
      }
    });

    // 对手方对『求和』意愿进行处理
    SocketEvent.register('sendPeaceResultRespApi', this.sendPeaceResultRespId, resp => {
      log('对手方处理了求和意愿，返回：', resp);
      if (resp.code === 'success') {
        const result = resp.data.result;
        if (this.reject === result) {
          Toast.show('对方拒绝和棋');
        }
      } else if (resp.code === 'fail') {
        Toast.show(resp.msg);
      }
    });

    // 对方发起悔棋请求监听
    SocketEvent.register('backMoveRespApi', this.backMoveRespId, resp => {
      log('对方发起悔棋，返回：', resp);
      if (resp.code === 'success') {
        Modal.alert('系统提示', '对方请求悔棋', [
          {
            text: '拒绝', onPress: () => {
              playSound(btnSound);
              SocketEvent.emit(this.props.socket, 'backMoveResultApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                result: this.reject,
                battleId: this.props.battleId
              }, resp => {
                if (resp.code !== 'success') {
                  Toast.show(resp.msg);
                }
              });
            },
          },
          {
            text: '同意', onPress: () => {
              playSound(btnSound);
              SocketEvent.emit(this.props.socket, 'backMoveResultApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                result: this.agree,
                battleId: this.props.battleId
              }, resp => {
                if (resp.code === 'success') {
                  // 我方调用方法悔棋
                  this.props.handleBackMove();
                } else {
                  Toast.show(resp.msg);
                }
              });
            },
          },
        ]);
      }
    });
    // 对手方对『请求悔棋』意愿进行了处理
    SocketEvent.register('backMoveResultRespApi', this.backMoveResultRespId, resp => {
      log('对手方处理了悔棋意愿，返回：', resp);
      if (resp.code === 'success') {
        const result = resp.data.result;
        if (this.reject === result) {
          Toast.show('对方拒绝悔棋');
        } else {
          // 对方调用方法悔棋
          this.props.handleBackMove();
          Toast.show('请您走棋');
        }
      } else if (resp.code === 'fail') {
        Toast.show(resp.msg);
      }
    });
  };

  /**
   * 消息弹窗倒计时
   */
  handleChatMessageTimeout = () => {
    // 消息的最大显示时间（秒）
    const maxSeconds = 5 * 1000;

    this.chatIntervalId = setInterval(() => {
      const {userStartDate, enemyStartDate} = this.state;
      // 用户端消息
      if (this.state.userMsgShow) {
        if (userStartDate == null) {
          this.setState({userStartDate: new Date()});
        } else {
          // 计算时间差
          const v = new Date().getTime() - userStartDate.getTime();
          if (v >= maxSeconds) {
            this.setState({userMsgShow: false, userStartDate: null});
          }
        }
      }
      // 敌人端消息
      if (this.state.enemyMsgShow) {
        if (enemyStartDate == null) {
          this.setState({enemyStartDate: new Date()});
        } else {
          // 计算时间差
          const v = new Date().getTime() - enemyStartDate.getTime();
          if (v >= maxSeconds) {
            this.setState({enemyMsgShow: false, enemyStartDate: null});
          }
        }
      }
    }, 1000);
  };

  /**
   * 处理离线消息
   */
  handleOfflineMessageTimeout = () => {
    this.offlineIntervalId = setInterval(() => {
      // 重新取值，因为值可能是后面赋值上去的
      const {offlineTime, offlineTimeout, offlineMsgShow} = this.state;
      // 离线消息展示
      if (offlineMsgShow) {
        // 计算时间差
        const time = (new Date().getTime() - offlineTime);
        const dValue = Math.floor(((offlineTimeout * 1000) - time) / 1000);
        this.setState({
          offlineMsg: `对方网络连接中断...${dValue}s`,
        });
        if (dValue <= 0 || this.props.gameOver) {
          this.setState({offlineMsgShow: false, offlineMsg: null});
          clearInterval(this.offlineIntervalId);
        }
      }
    }, 1000);
  };

  /**
   * 处理观战用户的聊天信息
   */
  handleWatchChatTimeout = () => {
    this.watchChatIntervalId = setInterval(() => {
      const {watchChatCache, watchChatShow} = this.state;
      if (!watchChatShow && watchChatCache.length > 0) {
        const chatCacheLen = watchChatCache.length;
        const watchChatObj = watchChatCache[chatCacheLen - 1];
        watchChatCache.splice(0, chatCacheLen);
        this.setState({watchChatObj, watchChatShow: true, watchChatCache});
      }
    }, 120);
  };

  componentWillUnmount() {
    document.removeEventListener('visibilitychange', this.sendWatchCount);
    clearInterval(this.chatWindowIntervalId);
    clearInterval(this.chatIntervalId);
    clearInterval(this.offlineIntervalId);
    clearInterval(this.watchChatIntervalId);
    SocketEvent.unRegister(this.unRegisterServices);
  }

  /**
   * 聊天
   */
  userChat = () => {
    playSound(btnSound);
    if (this.props.gameOver || this.props.handleBattleData) {
      Toast.show('对战已经结束');
    } else {
      Modal.prompt('请输入聊天内容', '', [
        {text: '取消', onPress: () => playSound(btnSound)},
        {
          text: '发送', onPress: value => {
            playSound(btnSound);
            if (value.length === 0) {
              Toast.show('请输入有效的聊天内容');
            } else {
              const {chatHistory} = this.state;
              const {playOne, playTwo} = this.props;
              const roomUser = playOne.userId === this.props.userId ? playOne : playTwo;
              chatHistory.push({
                userId: this.props.userId,
                userName: roomUser.userName,
                content: value,
              });
              SocketEvent.emit(this.props.socket, 'chatApi', {
                userId: this.props.userId,
                roomId: this.props.roomId,
                content: value,
              }, resp => {
                if (resp.code !== 'success') {
                  Toast.show(resp.msg);
                }
              });
              this.setState({
                userMsg: value,
                userMsgShow: true,
                userStartDate: null,
                chatHistory,
                msgWindowShow: false,
              });
              delete this.chatWindowIntervalId;
            }
          },
        },
      ]);
    }
  };

  closeMsgWidow = e => {
    playSound(btnSound);
    this.setState({msgWindowShow: false});
    delete this.chatWindowIntervalId;
  };

  closeWatchWindow = e => {
    playSound(btnSound);
    this.setState({watchWindowShow: false});
  };

  /**
   * 观战用户窗口展示
   */
  watchWindowView = () => {
    const {watchUserList} = this.state;
    return (
      <div className={styles.watch}>
        <div className={styles.title}>
          <div title={'icon'}/>
          <span>观战人数</span>
        </div>

        <div className={styles.content}>
          <div className={styles.list}>
            {
              watchUserList.map((item, index) => {
                return (
                  <Row key={index} className={styles.row}>
                    <Col span={2} className={styles.colTitle}>{index + 1}.</Col>
                    <Col span={10} className={styles.colContent}>{item.userName}</Col>
                    {/*<Col span={2} className={styles.colTitle}>:</Col>*/}
                    {/*<Col span={10} className={styles.colContent}>{item.enemyId}</Col>*/}
                  </Row>
                );
              })
            }
            {/*空数据集展示*/}
          </div>
          <div className={styles.floor}>
            <Row>
              <Col span={8}/>
              <Col span={8}>
                <AdvancedBtn type="danger" text='关闭' onClick={e => this.closeWatchWindow(e)}/>
              </Col>
              <Col span={8}/>
            </Row>
          </div>
        </div>
      </div>
    );
  };

  /**
   * 消息窗口是否展示
   */
  msgWindowView = () => {
    const {chatHistory} = this.state;
    const {userId, playOne, playTwo} = this.props;
    const {userId: enemyUserId} = playOne.userId === userId ? playTwo : playOne;
    return (
      <div className={styles.msgWindow}>
        <div className={styles.title}>
          <div title={'icon'}/>
          <span>消息记录</span>
        </div>

        <div className={styles.content}>
          <div className={styles.list} ref={ref => this.listRef = ref}>
            {
              chatHistory.map((item, index) => {
                return (
                  <p key={`msg_${index}`}>
                    <span className={`${item.userId === 'system'
                      ? styles.system : item.userId === userId
                        ? styles.self : item.userId === enemyUserId
                          ? styles.enemys : styles.tourist}`}>{item.userName}：{item.content}</span>
                  </p>
                );
              })
            }
          </div>
          <div className={styles.floor}>
            <Row>
              <Col span={7}>
                <AdvancedBtn type='normal' text='常用语'/>
              </Col>
              <Col span={1}/>
              <Col span={7}>
                <AdvancedBtn type="normal" text='编辑' onClick={e => this.userChat(e)}/>
              </Col>
              <Col span={1}/>
              <Col span={8}>
                <AdvancedBtn type="danger" text='关闭' onClick={e => this.closeMsgWidow(e)}/>
              </Col>
            </Row>
          </div>
        </div>
      </div>
    );
  };

  /**
   * 将聊天消息拖到最底部
   */
  msgWindowToBottom = () => {
    // 防止创建多个interval
    if (!this.chatWindowIntervalId) {
      const maxTryCount = 100;
      let tryCount = 0;
      this.chatWindowIntervalId = setInterval(() => {
        if (this.listRef || ++tryCount >= maxTryCount) {
          if(this.listRef) {
            this.listRef.scrollTop = this.listRef.scrollHeight;
          }
          clearInterval(this.chatWindowIntervalId);
          delete this.chatWindowIntervalId;
          log('将聊天消息拖到最底部，已完成');
        }
      }, 1);
    }
  };

  /**
   * 显示菜单
   */
  showMenuList = () => {
    playSound(btnSound);

    const lineOneDataList = [];
    lineOneDataList.push({icon: <img src={chatImg} alt='' style={{width: 36}}/>, title: this.chat});
    lineOneDataList.push({icon: <img src={chatHistoryImg} alt='' style={{width: 36}}/>, title: this.chatHistory});
    lineOneDataList.push({icon: <img src={skinImg} alt='' style={{width: 36}}/>, title: this.skin});

    const lineTwoDataList = [];
    lineTwoDataList.push({icon: <img src={peaceImg} alt='' style={{width: 36}}/>, title: this.peace});
    lineTwoDataList.push({icon: <img src={backMoveImg} alt='' style={{width: 36}}/>, title: this.backMove});
    lineTwoDataList.push({icon: <img src={failImg} alt='' style={{width: 36}}/>, title: this.fail});

    const data = [[...lineOneDataList], [...lineTwoDataList]];
    ActionSheet.showShareActionSheetWithOptions({
        options: data,
        message: '菜单',
      },
      (buttonIndex, rowIndex) => {
        const itemName = buttonIndex > -1 ? data[rowIndex][buttonIndex].title : 'cancel';
        playSound(btnSound);
        // 如果正在处理结算的数据，此选项不生效
        if (this.props.handleBattleData) {
          Toast.show('正在结算，请稍候');
          return false;
        }
        if (this.props.gameOver) {
          // 若游戏结束，再点击菜单，则将积分弹窗调出来
          Toast.show('对局已结束');
          this.props.showGameOverWindow();
        } else {
          if (itemName === this.skin) {
            Toast.show('皮肤功能未开放')
          } else if (itemName === this.fail) {
            Modal.alert('系统提示', '确定认输吗?', [
              {text: '取消', onPress: () => playSound(btnSound)},
              {
                text: '确认', onPress: () => {
                  playSound(btnSound);
                  this.props.exitPk();
                },
              },
            ]);
          } else if (itemName === this.peace) {
            SocketEvent.emit(this.props.socket, 'sendPeaceApi', {
              userId: this.props.userId,
              roomId: this.props.roomId,
              battleId: this.props.battleId
            }, resp => {
              if (resp.code === 'success') {
                Toast.show('已发送求和请求');
              } else {
                Toast.show(resp.msg);
              }
            });
          } else if (itemName === this.backMove) {
            if (this.props.historyMoveStep.length <= 1) {
              Toast.show('空棋盘，操作无效');
            } else {
              // playTwo 是玩家，isRedMove 为当前落子方颜色
              const {playTwo, isRedMove} = this.props;
              if (playTwo.first === isRedMove) {
                Toast.show('我方落子时无法悔棋');
              } else {
                SocketEvent.emit(this.props.socket, 'backMoveApi', {
                  userId: this.props.userId,
                  roomId: this.props.roomId,
                  battleId: this.props.battleId
                }, resp => {
                  if (resp.code === 'success') {
                    Toast.show('已发送悔棋请求');
                  } else {
                    Toast.show(resp.msg);
                  }
                });
              }
            }
          } else if (itemName === this.chat) {
            // 直接打开聊天窗口
            this.userChat();
          } else if (itemName === this.chatHistory) {
            // 打开历史记录窗口
            this.setState({msgWindowShow: true});
            this.msgWindowToBottom();
          }
        }
      });
  }

  render() {
    const {playOne, playTwo, isRedMove} = this.props;
    const bBoss = resMap.get('black');
    const wBoss = resMap.get('white');
    const {enemyMsgShow, enemyMsg, offlineMsg, userMsgShow, userMsg, watchUserList, watchChatShow, watchChatObj} = this.state;
    const watchMsg = `[${watchChatObj?.userName}]: ${watchChatObj?.content}`;
    return (
      <React.Fragment>
        {/*消息体显示*/}
        <div className={styles.watchMsg}>
          {
            watchChatShow && <div
              onAnimationStart={e => this.setState({watchChatShow: watchMsg.length > 5})}
              onAnimationEnd={e => this.setState({watchChatShow: false})}>
              { watchMsg }
            </div>
          }
        </div>
        <div className={styles.player}>
          <Row className={styles.user}>
            <Col span={4}>
              <div className={styles.icon}>
                <div>
                  <img src={playOne.iconUrl || (playOne.first ? bBoss : wBoss)} width='100%' height='100%' alt={''}/>
                  <div ref={ref => this.playOneRef = ref} />
                </div>
              </div>
            </Col>
            <Col span={15} className={styles.body}>
              <Row>
                <Col span={14} className={styles.name}>{playOne.userName}</Col>
                <Col span={10} className={styles.score}>{playOne.score}</Col>
              </Row>
              <Row>
                <Col span={12} className={styles.allTime}>局时 <span>{secondsToMinuteStr(playOne.allTime)}</span></Col>
                <Col span={12}
                     className={styles.stepTime}>步时 <span>{secondsToMinuteStr(playOne.stepTime)}</span></Col>
              </Row>
            </Col>
            <Col span={5}>
              <div className={styles.floor}>
                <AdvancedBtn
                  type={'square'}
                  text='旁观'
                  onClick={e => {
                    playSound(btnSound);
                    this.setState({watchWindowShow: true});
                  }}/>
                <Badge text={watchUserList.length} className={styles.badge}/>
              </div>
            </Col>
          </Row>

          {/*敌方消息弹窗*/}
          <div className={styles.enemyMsg} hidden={!(enemyMsgShow)} onClick={e => this.setState({enemyMsgShow: false})}>
            <span>{enemyMsg}</span>
          </div>

          {/*敌方离线弹窗*/}
          <div className={styles.enemyMsg} hidden={!(offlineMsg)}>
            <span>{offlineMsg}</span>
          </div>

          <Row className={styles.enemy}>
            <Col span={4}>
              <div className={styles.icon}>
                <div>
                  <img src={playTwo.iconUrl || (playTwo.first ? bBoss : wBoss)} width={'100%'} height={'100%'} alt={''}/>
                  <div ref={ref => this.playTwoRef = ref} />
                </div>
              </div>
            </Col>
            <Col span={15} className={styles.body}>
              <Row>
                <Col span={14} className={styles.name}>{playTwo.userName}</Col>
                <Col span={10} className={styles.score}>{playTwo.score}</Col>
              </Row>
              <Row>
                <Col span={12} className={styles.allTime}>
                  局时 <span
                  className={(playTwo.allTime && playTwo.allTime <= config.allTimeoutTips) ? styles.timeout : ''}>
                      {secondsToMinuteStr(playTwo.allTime)}
                    </span>
                </Col>
                <Col span={12} className={styles.stepTime}>
                  步时 <span
                  className={(playTwo.stepTime && playTwo.stepTime <= config.stepTimeoutTips) ? styles.timeout : ''}>
                      {secondsToMinuteStr(playTwo.stepTime)}
                    </span>
                </Col>
              </Row>
            </Col>
            <Col span={5}>
              <div className={styles.floor}>
                <AdvancedBtn type={'square'} text='菜单' onClick={this.showMenuList}/>
              </div>
            </Col>
          </Row>
          {/*我方消息弹窗*/}
          <div className={styles.userMsg} hidden={!(userMsgShow)} onClick={e => this.setState({userMsgShow: false})}>
            <span>{userMsg}</span>
          </div>
          {/*消息弹窗组件*/}
          {(this.state.msgWindowShow && !this.props.gameOver) ? this.msgWindowView() : ''}
          {/*观战人员弹窗组件*/}
          {(this.state.watchWindowShow && !this.props.gameOver) && this.watchWindowView()}
        </div>
      </React.Fragment>
    );
  }
}

export default User;
